<?php
namespace app\common;
use app\BaseController;
use GuzzleHttp\Client;
use ZipArchive;

class Upgrade extends BaseController{
     //服务端域名不能修改哦
    protected $api = 'https://mp.xhm.net.cn';
    
    private $Client;
    
    // protected $client;
    
    // protected $iden = 'mp';
    
    // protected $app_id;
    
    // protected $v;
    
    // protected $upgrade = true;
    
    public function __construct() {
        $this->Client = new Client();
    }

    public function index($action='',$v=''){
        $this->client = new Client(['base_uri'=> $this->api,'verify' => false,'timeout'  => 30.0]);
        $this->app_id = AppModel::where(['iden'=>$this->iden,'is_delete'=>0])->value('app_id');
        if($this->app_id <= 0){
            return $this->error('升级失败，应用不存在'.$this->app_id);
        }
        $this->v = AppVersionModel::where('app_id',$this->app_id)->order('version_id','desc')->value('v');
        if(empty($this->v)){
            $this->upgrade = false;
        }
        if(empty($action)){
            return $this->version();
        }
        
        if(empty($v)){
            return $this->error('version');
        }
        return $this->$action($v);
    }
    public function version(){
        $response = $this->client->request('POST','api/version',['query'=>['v'=>$this->v,'iden'=>$this->iden,'domain'=>$_SERVER['HTTP_HOST']]]);
        $data = json_decode($response->getBody(), true);
        if($data['code'] == 0){
            if($this->v == $data['data']['v']){
                echo "当前版本v".$this->v;
                echo "<p>已是最新版本</p>";
                die;
            }elseif($this->upgrade){
                echo "<p>当前版本v".$this->v."</p>";
                echo "<p>待升级版本v".$data['data']['v'];
                echo " => <button class='upload'>点击升级</button></p>";
                echo "<p>==>升级内容:<==</p>";
                echo $data['data']['info'];
            }else{
                echo "<p> 你还没有安装 => <button class='upload'>点击安装</button></p>";
            }
            echo "<div class='info'></div>\n";
            echo "<script src='https://api.xhm.net/static/jquery/jquery.min.js'></script>\n";
            echo "<script language='javascript' type='text/javascript'>\n";    
            echo "$(function () {
                let row = '<p>下载中。。。</p>';
                $('.upload').on('click', function () {
                    $('.info').append(row);
                    $.post('/{$this->iden}/upgrade',{action:'download',v:{$data['data']['v']}},function(result){
                        if(result.code == 200){
                            row = '<p>解压中。。。</p>';
                            decompression({$data['data']['v']});
                        }else{
                            row = '<p>'+result.msg+'</p>';
                        }
                        $('.info').append(row);
                    })
                });
                function decompression(v){
                    $.post('/{$this->iden}/upgrade',{action:'decompression',v:v},function(result){
                        if(result.code == 200){
                            row = '<p>后台升级中。。。</p>';
                            move(v);
                        }else{
                            row = '<p>'+result.msg+'</p>';
                        }
                        $('.info').append(row);
                    })
                }
                function move(v){
                    $.post('/{$this->iden}/upgrade',{action:'move',v:v},function(result){
                        if(result.code == 200){
                            row = '<p>数据库升级中。。。</p>';
                            sql(v);
                        }else{
                            row = '<p>'+result.msg+'</p>';
                        }
                        $('.info').append(row);
                    })
                }
                function sql(v){
                    $.post('/{$this->iden}/upgrade',{action:'sql',v:v},function(result){
                        if(result.code == 200){
                            row = '<p>小程序上传中。。。</p>';
                            upload(v);
                        }else{
                            row = '<p>'+result.msg+'</p>';
                        }
                        $('.info').append(row);
                    })
                }
                function upload(v){
                    $.post('/{$this->iden}/upgrade',{action:'upload',v:v},function(result){
                        if(result.code == 200){
                            row = '<p>小程序部署中。。。</p>';
                            template(v);
                        }else{
                            row = '<p>'+result.msg+'</p>';
                        }
                        $('.info').append(row);
                    })
                }
                function template(v){
                    $.post('/{$this->iden}/upgrade',{action:'template',v:v},function(result){
                        if(result.code == 200){
                            row = '<p>升级完成</p>';
                        }else{
                            row = '<p>'+result.msg+'</p>';
                        }
                        $('.info').append(row);
                    })
                }
            });\n";    
            echo "\n </script>";    
        } else {
            die($data['msg']);
        }
    }
    public function download($v){
        if(empty($v)){
            return $this->error('要升级的版本不正确');
        }
        $dir = root_path().'phpCode/'.$this->iden.'/'.$v;
        if(!is_dir($dir)){
            mkdir($dir,0777,true);
        }
        $file = $dir.'/'.$v.'.zip';
        $res = $this->client->post('api/download',['save_to'=>$file,'query'=> ['v'=>$v,'iden'=>$this->iden,'domain'=>$_SERVER['HTTP_HOST']]]);
        if(file_exists($file)){
            return  $this->success('下载成功');
        }
        return $this->error('下载失败');
        
    }
    public function decompression($v){
        if(empty($v)){
            return $this->error('要升级的版本不正确');
        }
        $dir = root_path().'phpCode/'.$this->iden.'/'.$v;
        $file = $dir.'/'.$v.'.zip';
        if(!file_exists($file)){
            return $this->error('文件解压失败'.$file);
        }
        $zip=new ZipArchive;//新建一个ZipArchive的对象 
        if($zip->open($file)===TRUE){ 
            $zip->extractTo($dir); 
            $zip->close();
            unlink($file);
            $jsdir = [
                $dir .'/view/js/',
                $dir.'/view/cashier/js/'
            ];
            $domain = $_SERVER['HTTP_HOST'];
            foreach($jsdir as $d){
                if(is_dir($d)){
                    $files = scandir($d);
                    foreach($files as $val){
                        if(strstr($val,'.js')){
                            $str = file_get_contents($d.$val);
                            $str = preg_replace('/d\.xhmvip\.com/',$domain, $str);
                            file_put_contents($d.$val, $str);
                        }
                    }
                }
            }
            return  $this->success('文件解压成功');
        }
        return $this->error('文件解压失败');
    }
    public function move($v){
        if(empty($v)){
            return $this->error('要升级的版本不正确');
        }
        $dir = root_path().'phpCode/'.$this->iden.'/'.$v;
        $phpdir = $dir.'/php/';
        $manageDir = $dir.'/view/';
        if(is_dir($phpdir)){
            $res = doMoveDir($phpdir, root_path().'app/'.$this->iden.'/');
            if($res == false) return $this->error ('部署文件失败');
        }
        if(is_dir($manageDir)){
            $res = doMoveDir($manageDir, root_path().'public/'.$this->iden.'/');
            if($res == false) return $this->error ('部署文件失败');
        }
    
        return $this->success('移动文件成功');
    }
    public function sql($v){
        if(empty($v)){
            return $this->error('要安装的版本不正确');
        }
        $dir = root_path().'phpCode/'.$this->iden.'/'.$v;
        
        $sqlFile = $dir.'/install.sql';
        $msg = '安装完成';
        if($this->upgrade){
            $sqlFile = $dir.'/update.sql';
            $msg = '升级完成';
        }
        if(!file_exists($sqlFile)){
            return $this->success($msg);
        }
       
        $sql = file_get_contents($sqlFile);
        $sqls = explode(';'."\r", $sql);
        if(empty($sql)) return $this->success ($msg);
        Db::startTrans();
        try{
            foreach($sqls as $val){
               $val = trim($val);
               if(!empty($val)){
                  Db::execute($val);
               }
            }
            Db::commit();
            return $this->success ($msg);
        } catch (\Exception $e){
            Db::rollback();
            return $this->error($e->getMessage());
        }
    }
    public function upload($v){
        $DataSettingLogic = new DataSettingLogic();
        $setting = $DataSettingLogic->getData('open');
        if(empty($setting['miniapp_id']) || empty($setting['miniapp_auth'])){
            return $this->error('请先配置开发的小程序及小程序上传秘钥');
        }
        $response = $this->client->request('POST','api/upload',['query'=>['v'=>$v,'iden'=>$this->iden,'domain'=>$_SERVER['HTTP_HOST'],'wxAppId'=>$setting['miniapp_id'],'wxUploadKey'=>$setting['miniapp_auth']]]);
        $data = json_decode($response->getBody(), true);
        if($data['code'] == 0){
            return  $this->success($data['msg']);
        } else {
            $this->error($data['msg']);
        }
        return $this->success($setting);
    }
    public function template($v){
        if(null === $app_id = AppModel::where('iden',$this->iden)->value('app_id')){
            return $this->error('应用不正确');
        }
        $OpenPlatformMiniappCodeHelper = new OpenPlatformMiniappCodeHelper();
        $res = $OpenPlatformMiniappCodeHelper->getDrafts();
        if(empty($res['draft_list'])){
            return $this->error('第三方开放平台草稿箱没有草稿,应该上传小程序故障了');
        }
        $draft_id = $res['draft_list'][count($res['draft_list']) - 1]['draft_id'];
        if(empty($draft_id)){
            return $this->error('第三方开放平台草稿箱没有草稿,应该上传小程序故障了');
        }
        $res = $OpenPlatformMiniappCodeHelper->createFromDraft($draft_id);
        if($res['errcode'] != 0){ //如果失败直接报错
            return $this->error($res['errmsg']);
        }
        $list = $OpenPlatformMiniappCodeHelper->getTemplateList();
        if($list['errcode'] != 0){
            return $this->error($res['errmsg']);
        }
        $myList = $list['template_list'];
        $create = array_column($myList,'create_time');
        array_multisort($create,SORT_DESC,$myList);
        $template_info = $myList[0];
        $AppVersionModel = new AppVersionModel();
        $AppVersionModel->save([
            'app_id' => $app_id,
            'template' => $template_info['template_id'],
            'v' => $v,
            'content' => $template_info['user_desc'],
        ]);
        return $this->success($template_info);
    }
}
